A few very simple characteristics of the Scala language. No Spark specifics yet.
Mostly taken from A short primer on Scala. See also additional documentation in Scala overviews and the Scala cheatsheet
In terms of general syntax, Scala is quite similar to Java. One difference is that it is less picky with semicolons: they are optional at the end of the line.
Mutable and immutable values. Type inference
In [6]:
// A mutable variable, defined with explicit type specification
var a: Int = 5
a = a + 1
println(a)
// Inmutable variables
val v1: Double = 6.2
val v2: String = "Hi!"
println( v1, v2)
// Same as before, but now we use type inference
val v1 = 6.2
val v2 = "Hi!"
println( v1, v2)
println( v1.getClass, v2.getClass )
In [6]:
/* Define a function. This one is a one-liner, otherwise we would use braces */
def fact(n: Int): Int = if (n == 0) 1 else n*fact(n-1)
In [7]:
// Use the function
fact(10)
Out[7]:
In [2]:
// A function, with type specification
// (if the context was clear, we could use type inference)
val cube = (x : Int) => x*x*x
cube(7)
Out[2]:
In [4]:
// Same thing, but using explicit return type specification
val cube: Int => Double = x => x*x*x
cube(5)
Out[4]:
In [9]:
// If the function is more complex, we use a brace block
val cubeOrSquare = (x: Int) => { if( x < 10 )
x*x*x
else
x*x }
print( cubeOrSquare(7), cubeOrSquare(11) )
There is also a shorthand used in which we use the underscore (_
) as a placeholder for anonymous arguments, and we skip the argument list. See below
In [5]:
// A function that takes another function and a value, and applies the function to the square of the value
def applySquared( func: Int => Int, value: Int) = func( value*value )
// Prepare the function we will pass
val minusOne = (x : Int) => x - 1
// This should compute x^2 - 1
print( applySquared( minusOne, 3 ) )
// We can also pass directly an anonymous function. This is x^2 + 2
applySquared( _ + 2, 6 )
Out[5]:
In [3]:
/* Define a class */
class Point( xc: Int, yc: Int ) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
}
override def toString(): String = "(" + x + ", " + y + ")";
}
/* Create an instance, and operate with it */
val p = new Point( 10, 11 )
p.move( 2, -1 )
println( p )
See Scala collections for documentation.
In [11]:
var l = List( 1, 2, 3, 4, 5 )
In [12]:
l.reverse
Out[12]:
In [13]:
var s = Set( "a", "b", "c", "d")
In [14]:
s.contains( "c" )
Out[14]:
In [15]:
s & Set("a","c","f")
Out[15]:
In [25]:
val r = Range(1,10)
r
Out[25]:
There is also a special syntax to define ranges using to
or until
In [27]:
1 to 10
Out[27]:
In [32]:
// define a range with a fractional increment, and convert the result to Array
(1.0 until 10.0 by 0.5).toArray
Out[32]:
In [12]:
val numbers = List(1,2,3,4)
// We use here an anonymous function
numbers.map( x => 2 * x )
Out[12]:
In [13]:
// Same, but now with the shorthand using the underscore, which is interpreted as a reference to an anonymous argument
numbers.map( 2 * _ )
Out[13]:
In [16]:
// Another example
numbers.filter( _ <= 2 )
Out[16]:
Another variant: the reduceLeft
function applies a binary operation (two parameters) successively, until all elements in the collection have been consumed:
In [16]:
numbers.reduceLeft( (a, b) => a + b )
Out[16]:
In [17]:
// Again, using the underscore shorthand (each underscore refers to one of the two parameters)
numbers.reduceLeft( _ + _ )
Out[17]: